#pragma once

#include "disk/my_disk_volume.h"
#include "util/my_cache_key.h"
#include "mem/my_slru_cache.h"
#include "comm/my_buf.h"
#include "comm/my_hrtime.h"
#include "comm/my_chash.h"

#define MY_CACHE_MEM_NUM                            16

struct my_cache_mem_layer_s {
    my_slru_cache_t                 slru_cache[MY_CACHE_MEM_NUM];
};

typedef struct my_cache_mem_layer_s my_cache_mem_layer_t;

void
my_cache_mem_layer_open(my_cache_mem_layer_t *mem_layer, int nlists,
    int64_t max_item, int64_t max_bytes);

void
my_cache_mem_layer_close(my_cache_mem_layer_t *mem_layer);

my_bool_t
my_cache_mem_layer_get(my_cache_mem_layer_t *mem_layer, my_cache_key_t *key,
    my_buf_chain_t *data);

void
my_cache_mem_layer_put(my_cache_mem_layer_t *mem_layer, my_cache_key_t *key,
    my_buf_chain_t *data);

void
my_cache_mem_layer_remove(my_cache_mem_layer_t *mem_layer, my_cache_key_t *key);


typedef struct my_cache_storage_layer_s my_cache_storage_layer_t;

struct my_cache_storage_layer_s {
    my_spin_lock_t              lock;       // protect the following members
    my_rbtree_t                 tree;
    my_queue_t                  head;
    my_rbtree_node_t            sentinel;

    my_rwlock_t                 rwlock;     // protect the chash tabe, 
    my_chash_t                  *chash;
};

void
my_cache_storage_layer_init(my_cache_storage_layer_t *storage_layer);

void
my_cache_storage_layer_add_storage(my_cache_storage_layer_t *storage_layer,
    my_disk_volume_t *volume, my_bool_t kicked);

static void
my_cache_storage_layer_rebuild_helper(my_cache_storage_layer_t *storage_layer);

void
my_cache_storage_layer_build(my_cache_storage_layer_t *storage_layer);

void
my_cache_storage_layer_kicked(my_cache_storage_layer_t *storage_layer,
    my_disk_volume_t *volume);

my_disk_volume_t *
my_cache_storage_layer_get_volume(my_cache_storage_layer_t *storage_layer, const char *key);

void
my_cache_storage_layer_release(my_cache_storage_layer_t *storage_layer);